package com.qishanor.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qishanor.framework.constant.CommonConstant;
import com.qishanor.framework.mybatis.datascope.DataScope;
import com.qishanor.system.mapper.SysDeptMapper;
import com.qishanor.system.mapper.SysDeptRelationMapper;
import com.qishanor.system.model.SysDept;
import com.qishanor.system.model.SysDeptRelation;
import com.qishanor.system.service.SysDeptRelationService;
import com.qishanor.system.service.SysDeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 部门表 服务实现类
 * @author: 周振林
 * @date: 2022-04-12
 * @Copyright: 博客：http://www.zhouzhenlin.com - 沉淀、分享、成长、让自己和他人都有所收获
 **/

@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    @Autowired
    private SysDeptRelationService sysDeptRelationService;


    @Override
    public List<Tree<Integer>> tree(String deptName) {

        // 查询全部部门
        List<SysDept> deptAllList = baseMapper.selectList(Wrappers.lambdaQuery(SysDept.class).like(StrUtil.isNotBlank(deptName),SysDept::getName,deptName));
        // 查询数据权限内部门
        List<Integer> deptOwnIdList = baseMapper.selectListByScope(Wrappers.emptyWrapper(),new DataScope().setScopeName("id")).stream()
                .map(SysDept::getId).collect(Collectors.toList());

        // 权限内部门
        List<TreeNode<Integer>> collect = deptAllList.stream()
                .filter(dept -> dept.getId().intValue() != dept.getParentId())
                .sorted(Comparator.comparingInt(SysDept::getSort)).map(dept -> {
                    TreeNode<Integer> treeNode = new TreeNode();
                    treeNode.setId(dept.getId());
                    treeNode.setParentId(dept.getParentId());
                    treeNode.setName(dept.getName());
                    treeNode.setWeight(dept.getSort());
                    // 有权限不返回标识
                    Map<String, Object> extra = new HashMap<>(8);
                    extra.put("isLock", !deptOwnIdList.contains(dept.getId()));
                    extra.put("createTime", dept.getCreateTime());
                    treeNode.setExtra(extra);
                    return treeNode;
                }).collect(Collectors.toList());

        // 模糊查询 不组装树结构 直接返回 表格方便编辑
        if (StrUtil.isNotBlank(deptName)) {
            return collect.stream().map(node -> {
                Tree<Integer> tree = new Tree<>();
                tree.putAll(node.getExtra());
                BeanUtils.copyProperties(node, tree);
                return tree;
            }).collect(Collectors.toList());
        }
        return TreeUtil.build(collect, CommonConstant.DEPT_TREE_ROOT_ID);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDept(SysDept sysDept) {
        baseMapper.insert(sysDept);
        sysDeptRelationService.insertDeptRelation(sysDept);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDept(SysDept sysDept) {
        // 更新部门
        baseMapper.updateById(sysDept);
        // 更新部门关系
       sysDeptRelationService.updateDeptRelation(sysDept);
        return Boolean.TRUE;
    }

    /**
     * 删除部门
     * @param id 部门 ID
     * @return 成功、失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeDeptById(Integer id) {
        //查询该部门下的所有子部门
        List<Integer> subDeptIds = sysDeptRelationService.list(Wrappers.lambdaQuery(SysDeptRelation.class).eq(SysDeptRelation::getAncestor, id))
                .stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList());

        //删除部门表
        this.removeByIds(subDeptIds);
        //删除部门级联关系
        sysDeptRelationService.deleteDeptRealtion(id);
        //sysDeptRelationMapper.delete(Wrappers.lambdaQuery(SysDeptRelation.class).in(SysDeptRelation::getDescendant,subDeptIds));

        return Boolean.TRUE;
    }
}
